package com.onlyxiahui.wofa.server.socket.netty.boot;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

import com.onlyxiahui.framework.action.dispatcher.general.GeneralMessageHandler;
import com.onlyxiahui.wofa.server.net.core.Server;
import com.onlyxiahui.wofa.server.net.core.session.SocketSessionHandler;
import com.onlyxiahui.wofa.server.socket.netty.common.coder.NettyCodecCreater;
import com.onlyxiahui.wofa.server.socket.netty.common.util.SslContextUtil;
import com.onlyxiahui.wofa.server.socket.netty.config.NetServerProperties;
import com.onlyxiahui.wofa.server.socket.netty.config.SslData;
import com.onlyxiahui.wofa.server.socket.netty.config.TcpServerData;
import com.onlyxiahui.wofa.server.socket.netty.config.WebSocketServerData;
import com.onlyxiahui.wofa.server.socket.netty.tcp.SocketServer;
import com.onlyxiahui.wofa.server.socket.netty.websocket.WebSocketServer;

import io.netty.handler.ssl.SslContext;

/**
 *
 * Description 容器启动后要初始化服务<br>
 * Date 2020-08-06 20:53:17<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
public class NettyServerRunner implements ApplicationRunner {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private GeneralMessageHandler generalMessageHandler;
	@Autowired
	private SocketSessionHandler socketSessionHandler;
	@Autowired
	private NetServerProperties netServerProperties;

	@Autowired(required = false)
	private NettyCodecCreater codecCreater;

	boolean run = false;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		if (!run) {
			run = true;
			if (logger.isInfoEnabled()) {
				logger.info("服务初始化");
			}
			startServer();
		}
	}

	void startServer() throws Exception {
		List<TcpServerData> tcpServers = netServerProperties.getTcpServers();
		List<WebSocketServerData> webSocketServers = netServerProperties.getWebSocketServers();

		if (null != tcpServers) {
			for (TcpServerData s : tcpServers) {
				int port = s.getPort();
				SslData ssl = s.getSsl();
				SslContext sslContext = null;
				if (null != ssl && null != ssl.getCertificatePath() && !ssl.getCertificatePath().isEmpty()) {
					String certificatePath = ssl.getCertificatePath();
					String keyPath = ssl.getKeyPath();
					String keyPassword = ssl.getKeyPassword();
					sslContext = SslContextUtil.createSslContext(certificatePath, keyPath, keyPassword);
				}
				SocketServer server = new SocketServer(generalMessageHandler, socketSessionHandler, codecCreater, sslContext);
				new StartThread(server, port).start();
			}
		}

		if (null != webSocketServers) {
			for (WebSocketServerData s : webSocketServers) {
				int port = s.getPort();
				String websocketPath = s.getPath();
				SslData ssl = s.getSsl();
				SslContext sslContext = null;
				if (null != ssl && null != ssl.getCertificatePath() && !ssl.getCertificatePath().isEmpty()) {
					String certificatePath = ssl.getCertificatePath();
					String keyPath = ssl.getKeyPath();
					String keyPassword = ssl.getKeyPassword();
					sslContext = SslContextUtil.createSslContext(certificatePath, keyPath, keyPassword);
				}
				WebSocketServer server = new WebSocketServer(websocketPath, generalMessageHandler, socketSessionHandler, sslContext);
				new StartThread(server, port).start();
			}
		}
	}

	static class StartThread extends Thread {

		private Server server;
		private int port;

		public StartThread(Server server, int port) {
			this.server = server;
			this.port = port;
		}

		public void run() {
			server.start(port);
		}
	}
}
